package com.totoro.tyrank.manager;

import com.totoro.tyrank.TyRank;
import com.totoro.tyrank.constants.StaticSystemVarConst;
import com.totoro.tyrank.data.LanguageData;
import com.totoro.tyrank.utils.ColorUtil;
import lombok.Getter;
import lombok.SneakyThrows;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.Plugin;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 语言配置文件管理器
 */
public class LanguageManager {

    private final Plugin plugin;

    private static final String LANGUAGE_PATH = TyRank.getInstance().getDataFolder().getPath() + StaticSystemVarConst.FILE_SEPARATOR + StaticSystemVarConst.LANGUAGE_CONFIG_DEFAULT_NAME;
    private static final File LANGUAGE_FILE = new File(LANGUAGE_PATH);

    @Getter
    private final LanguageData languageData;

    public LanguageManager(Plugin plugin) {
        languageData = new LanguageData();
        this.plugin = plugin;
    }

    public void createLanguageFile() {
        if(! LANGUAGE_FILE.exists()) {
            plugin.saveResource(StaticSystemVarConst.LANGUAGE_CONFIG_DEFAULT_NAME, false);
        }
    }

    public void reloadLanguage() {
        Class<LanguageData.Gui> guiClass = LanguageData.Gui.class;
        Class<LanguageData.Msg> msgClass = LanguageData.Msg.class;
        LanguageData.Gui gui = loadTypeConfig(guiClass, getLanguageSection(StaticSystemVarConst.LANGUAGE_GUI));
        LanguageData.Msg msg = loadTypeConfig(msgClass, getLanguageSection(StaticSystemVarConst.LANGUAGE_MSG));
        languageData.setGui(gui);
        languageData.setMsg(msg);
    }

    @SneakyThrows
    private <T> T loadTypeConfig(Class<T> c, ConfigurationSection section) {
        LanguageData outer = new LanguageData();
        T t = instantiateInnerClass(c, outer);
        Field[] fields = c.getDeclaredFields();
        for (Field field : fields) {
            String fieldName = field.getName();
            field.setAccessible(true);
            Object o = section.get(fieldName);
            if(o instanceof String) {
                o = ColorUtil.color((String) o);
            }
            if(o instanceof List) {
                o = ((List<String>) o).stream().map(ColorUtil::color).collect(Collectors.toList());
            }
            field.set(t, o);
        }
        return t;
    }

    /**
     * 实例化成员内部类
     * @param innerClass 内部类的Class对象
     * @param outerInstance 外部类实例
     * @param <T> 内部类类型
     * @return 内部类实例
     */
    private  <T> T instantiateInnerClass(Class<T> innerClass, LanguageData outerInstance) {
        try {
            Constructor<T> constructor = innerClass.getDeclaredConstructor(LanguageData.class);
            constructor.setAccessible(true);
            return constructor.newInstance(outerInstance);
        } catch (Exception e) {
            System.err.println("实例化内部类失败: " + e.getMessage());
            return null;
        }
    }

    private YamlConfiguration getLanguageConfig() {
        if(! LANGUAGE_FILE.exists()) {
            createLanguageFile();
        }
        return YamlConfiguration.loadConfiguration(LANGUAGE_FILE);
    }

    private ConfigurationSection getLanguageSection(String type) {
        YamlConfiguration languageConfig = getLanguageConfig();
        return languageConfig.getConfigurationSection(type);
    }

}
